from fastapi import FastAPI, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import List, Optional
import uvicorn

from database import get_db, engine
import models
from chat import ChatService
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import StreamingResponse

# 创建数据库表
models.Base.metadata.create_all(bind=engine)

app = FastAPI(title="LLM Chat API")
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],  # Vue默认开发端口
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有HTTP方法
    allow_headers=["*"],  # 允许所有请求头
)
chat_service = ChatService()

class MessageRequest(BaseModel):
    conversation_id: int
    message: str

class ConversationCreate(BaseModel):
    title: Optional[str] = None

class ModelSwitchRequest(BaseModel):
    model_name: str  # "Deepseek" 或 "Moonshot"

class LoginRequest(BaseModel):
    username: str
    password: str

# 登录接口（简化版）
@app.post("/login")
def login(request: LoginRequest, db: Session = Depends(get_db)):  # 使用模型接收数据
    user = db.query(models.User).filter(models.User.username == request.username).first()
    if not user or user.password != request.password:  # 使用 request.xxx 访问字段
        raise HTTPException(status_code=401, detail="用户名或密码错误")
    return {"user_id": user.id, "username": user.username}

# 会话管理接口
@app.post("/conversations", response_model=dict)
def create_conversation(
    conversation: ConversationCreate,
    user_id: int,
    db: Session = Depends(get_db)
):
    new_conv = chat_service.create_conversation(db, user_id, conversation.title)
    return {"conversation_id": new_conv.id, "title": new_conv.title}

@app.get("/conversations", response_model=List[dict])
def get_user_conversations(user_id: int, db: Session = Depends(get_db)):
    convs = chat_service.get_conversations(db, user_id)
    return [{"id": c.id, "title": c.title, "updated_at": c.updated_at} for c in convs]

# 聊天接口
@app.post("/chat", response_model=dict)
async def chat(
    request: MessageRequest,
    db: Session = Depends(get_db)
):
    try:
        result = await chat_service.chat(db, request.conversation_id, request.message)
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/chat/stream")
async def chat_stream(
    request: MessageRequest,
    db: Session = Depends(get_db)
):
    try:
        # 返回流式响应
        return StreamingResponse(
            chat_service.chat_stream(db, request.conversation_id, request.message),
            media_type="text/event-stream"  # SSE 媒体类型
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 切换模型接口
@app.post("/switch-model")
def switch_model(request: ModelSwitchRequest):
    chat_service.set_model(request.model_name)
    return {"message": f"已切换到 {request.model_name} 模型"}

# 获取会话消息
@app.get("/conversations/{conversation_id}/messages", response_model=List[dict])
def get_messages(conversation_id: int, db: Session = Depends(get_db)):
    messages = chat_service.get_conversation_messages(db, conversation_id)
    return [{"id": m.id, "content": m.content, "role": m.role, "created_at": m.created_at} for m in messages]

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8088)